package com.pisolution.scheduler.runtime.worker.processor;

import com.pisolution.scheduler.core.utils.JsonUtils;
import com.pisolution.scheduler.datasource.instance.ExecutionState;
import com.pisolution.scheduler.remote.command.Command;
import com.pisolution.scheduler.remote.command.CommandType;
import com.pisolution.scheduler.remote.processor.NettyRequestProcessor;
import com.pisolution.scheduler.runtime.SchedulerContext;
import com.pisolution.scheduler.runtime.master.processor.DBAckCommand;
import com.pisolution.scheduler.runtime.worker.cache.ResponseCache;

import com.google.common.base.Preconditions;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 处理管理节点移交给工作节点的数据库更新确认请求 请求处理逻辑详见具体的处理方法描述.
 *
 * @see #process(Channel, Command)
 * @author sora
 * @version 0.1.0
 */
public class DBAckProcessor implements NettyRequestProcessor {
    private static final Logger LOGGER = LoggerFactory.getLogger(DBAckProcessor.class);

    // -------------------------------------------------------------------------------------------------

    /** 用于移除缓存. */
    private final ResponseCache cache;

    // -------------------------------------------------------------------------------------------------
    //  初始化
    // -------------------------------------------------------------------------------------------------

    /**
     * 初始化 {@link DBAckProcessor}.
     */
    public DBAckProcessor() {
        this.cache = SchedulerContext.get(ResponseCache.class);
    }

    // -------------------------------------------------------------------------------------------------
    //  请求处理
    // -------------------------------------------------------------------------------------------------

    @Override
    public void process(Channel channel, Command command) {
        // 1. 校验接收到的指令类型是否与待处理的指令类型一致.
        Preconditions.checkArgument(
            CommandType.DB_ACK_REQUEST == command.getType(),
            "Received unrecognized command with type %s",
            command.getType()
        );

        // 2. 反序列化指令内容.
        final DBAckCommand cmd = JsonUtils.deserialize(command.getBody(), DBAckCommand.class);

        LOGGER.info("Received the interaction command {}.", cmd);

        // 3. 如果指令为空 则不予处理 忽略此指令 否则移除缓存中的确认指令.
        if (cmd == null) {
            return;
        }

        if (cmd.getStatus() == ExecutionState.SUCCESS.getCode()) {
            this.cache.removeAckCache(cmd.getTaskId());
        }
    }
}
